package com.example.drug.service.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import cn.hutool.core.date.DateUtil;
import com.example.common.entity.*;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.example.common.entity.ClientPatientsInfo;
import com.example.common.entity.DoctorBaseInfo;
import com.example.common.entity.EnumConfig;
import com.example.common.entity.OrderMain;
import com.example.common.entity.Pharmacist;
import com.example.common.entity.RxDrugs;
import com.example.common.entity.RxMain;
import com.example.common.enums.ChkStatus;
import com.example.common.enums.DType;
import com.example.common.sendhttp.CaSendMessage;
import com.example.common.sendhttp.WxSendMessage;
import com.example.common.support.ApiException;
import com.example.common.cqsupervision.dto.ca.Pharm.CA;
import com.example.common.utils.CheckUtils;
import com.example.common.utils.XmlUtils;
import com.example.common.vo.WxSubScribeMessageVo;
import com.example.common.utils.MapUtils;
import com.example.common.utils.RedisUtils;
import com.example.drug.dto.req.RxListReq;
import com.example.drug.dto.req.RxMainReq;
import com.example.drug.dto.req.UnCheckRecipeReq;
import com.example.drug.dto.resp.*;
import com.example.drug.dto.resp.PatientsInfo;
import com.example.drug.jpa.*;
import com.example.drug.mapper.OrderRxMainMapper;
import com.example.drug.mapper.PatientMapper;
import com.example.drug.mapper.RxOrderMapper;
import com.example.drug.service.PrescriptionService;
import com.example.drug.utils.UserUtils;

import org.springframework.stereotype.Service;

import cn.hutool.core.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;

@Service
@Slf4j
public class PrescriptionServiceImpl implements PrescriptionService {


    @Resource
    private OrderRxMainMapper orderRxMainMapper;

    @Resource
    private RxDrugsRepository rxDrugsRepository;

    @Resource
    private RxMainRepository rxMainRepository;

    @Resource
    private PharmacistRepository pharmacistRepository;
    @Resource
    private DiseaseInfoRepository diseaseInfoRepository;
    @Resource
    private ImgRepository imgRepository;

    @Resource
    private EnumConfigRepository enumConfigRepository;

    @Resource
    private UserUtils userUtils;
    @Resource
    private OrderMainRepository orderMainRepository;
    @Resource
    private DoctorBaseInfoRepository doctorBaseInfoRepository;
    @Resource
    private ClientPatientsInfoRepository clientPatientsInfoRepository;

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private CaSendMessage caSendMessage;

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;

    @Resource
    HospitalDepartmentRepository hospitalDepartmentRepository;

    @Resource
    PatientMapper patientMapper;

    @Resource
    RxOrderMapper rxOrderMapper;
    @Resource
    MsgConfigRepository msgConfigRepository;
    @Resource
    private WxSendMessage wxSendMessage;
    
    @Value("${doctormappID}")
    private String doctormappID;

    @Value("${doctormappsecret}")
    private String doctormappsecret;


    @Override
    public Map<String, Object> getPharmacistMsg(Long DCID, UnCheckRecipeReq req) {
        Map<String, Object> result = new HashMap<>();
        long count = orderRxMainMapper.countPharmacistMsg(DCID);
        List<PharmacistOrder> query = orderRxMainMapper.getPharmacistMsg(DCID, (req.getPage() - 1) * req.getLimit(), req.getLimit());
        result.put("total", count);
        result.put("list", query);
        return result;
    }

    @Override
    public PharmacistDetail getPharmacistdetails(Long DCID, String RxOrderNO) {
        PharmacistDetail obj = orderRxMainMapper.getPharmacistdetails(DCID, RxOrderNO);
        CheckUtils.checkNull(obj, new ApiException(10000, "数据不存在"));
        RxMain rxMain = rxMainRepository.findById(RxOrderNO).orElseThrow(() -> new ApiException(1, "未查询到数据"));
        //拼接诊断病名
        List<Long> disIds = Arrays.stream(rxMain.getDisIds().split(",")).map(Long::parseLong)
                .collect(Collectors.toList());
        StringBuilder sb = new StringBuilder();
        diseaseInfoRepository.findByIdIn(disIds).stream()
                .map(m -> m.getCode() + " " + m.getDiseaseName()).forEach(str -> {
            sb.append(str);
            sb.append(";");
        });
        List<RxDrugs> list = rxDrugsRepository.findByRxOrderNo(RxOrderNO);
        obj.setDialectical(sb.substring(0, sb.length() - 1));
        List<PharmacistDrugs> RxDrugs = list.stream().map(m -> {
            PharmacistDrugs resp = new PharmacistDrugs();
            BeanUtil.copyProperties(m, resp);
            resp.setSuggest(m.getMedWay() + "；每日" + m.getFreq() + "；" + m.getDoes() + m.getDoesUnit() + "/次；" + m.getDay() + "天");
            return resp;
        }).collect(Collectors.toList());
        obj.setRxDrugs(RxDrugs);
        return obj;
    }

    @Override
    public Map<String, Object> getPatientsInfo(long pid) {
        SimpleDateFormat fdate = new SimpleDateFormat("yyyy.MM.dd");
        ClientPatientsInfo patient = clientPatientsInfoRepository.findById(pid).orElseThrow(() -> new ApiException(1, "没有患者信息"));
        Map<String, Object> p = new HashMap<>();
        p.put("Header", patient.getHeader());
        p.put("Name", patient.getName());
        p.put("Sex", patient.getSex());
        p.put("Age", DateUtil.betweenYear(patient.getBirthday(), new Date(), Boolean.FALSE));


        Map<String, Object> RxInfo = null;
        RxMain Rx = rxMainRepository.findByLastOne(pid);
        if (Rx != null) {
            List<Map<String, Object>> zRx = null;
            List<Map<String, Object>> xRx = null;
            if (Rx.getDType() == 1) {
                zRx = rxOrderMapper.selectzRxInfoList(Rx.getRxOrderNO());
            }
            if (Rx.getDType() == 2 || Rx.getDType() == 3) {
                xRx = rxOrderMapper.selectxRxInfoList(Rx.getRxOrderNO());
            }

            RxInfo = new HashMap<>();
            RxInfo.put("CreateTime", fdate.format(Rx.getCreateTime()));
            RxInfo.put("Dialectical", Rx.getDialectical());
            RxInfo.put("ZRx", zRx);
            RxInfo.put("xRx", xRx);
        }

        Map<String, Object> ParInfo = null;
        Map<String, Object> pat = rxOrderMapper.selectLastOrder(pid);
        if (pat != null) {
            DoctorBaseInfo doctor = doctorBaseInfoRepository.findByDcId(Long.valueOf(pat.get("dc_id_bigint").toString()));
            HospitalDepartment depart = hospitalDepartmentRepository.findById(doctor.getDepartId()).orElse(null);
            RxMain rxMain = rxMainRepository.findLastOrder(pat.get("order_no_nvarchar").toString());

            ParInfo = new HashMap<>();
            ParInfo.put("Allergy", pat.get("allergy_nvarchar"));
            ParInfo.put("PastDisease", pat.get("past_disease_nvarchar"));
            ParInfo.put("ReceiveTime", fdate.format((Date) pat.get("receive_time_datetime")));
            ParInfo.put("Name", doctor.getName());
            ParInfo.put("dName", depart.getName());
            ParInfo.put("Title", doctor.getTitle());
            ParInfo.put("Dialectical", rxMain != null ? rxMain.getDialectical() : "");
        }


        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("Patient", p);
        hashMap.put("Rx", RxInfo);
        hashMap.put("Par", ParInfo);
        return hashMap;
    }

    @Override
    public String UpdateRxMain(Long DCID, RxMainReq re) {
        RxMain obj = rxMainRepository.findById(re.getRxOrderNO()).orElse(null);
        CheckUtils.checkNull(obj, new ApiException(10000, "订单不存在"));
        if (!obj.getChkDcId().equals(DCID)) {
            CheckUtils.checkNull(null, new ApiException(10000, "用户不存在"));
        }
        if (obj.getChkStatus() == 1) {
            CheckUtils.checkNull(null, new ApiException(10000, "处方已审核"));
        }
        if (!re.getChkStatus().equals(1) && !re.getChkStatus().equals(2)) {
            CheckUtils.checkNull(null, new ApiException(10000, "参数错误"));
        }

        Pharmacist objdoc = pharmacistRepository.findById(DCID).orElse(null);
        if (objdoc.getDisable()) {
            CheckUtils.checkNull(null, new ApiException(10000, "用户已禁用"));
        }

        obj.setChkStatus(re.getChkStatus() == 1 ? obj.getChkStatus() : re.getChkStatus());
        obj.setChkTime(new Date());
        obj.setFailureReason(re.getFailureReason());
        obj.setFailureRemark(re.getFailureRemark());
        if (re.getChkStatus() == 1) {
            // 审核通过 ca签名
            OrderMain order = orderMainRepository.findById(obj.getOrderNO()).orElse(null);
            DoctorBaseInfo doctor = doctorBaseInfoRepository.findByDcId(order.getDcId());
            Pharmacist pharmacist = pharmacistRepository.findById(obj.getChkDcId()).orElse(null);
            ClientPatientsInfo patient = clientPatientsInfoRepository.findById(order.getPid()).orElse(null);

            CA ca = new CA();
            ca.setMedicalRecordNo(obj.getRxOrderNO());
            ca.setDoctorCode(doctor.getDcId().toString());
            ca.setDoctorName(doctor.getName());
            ca.setTrialPharmCode(pharmacist.getDcId().toString());
            ca.setTrialPharmName(pharmacist.getName());
            ca.setPatientName(patient.getName());
            ca.setPatientSFZH(patient.getIdNo());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            ca.setRecipeDate(sdf.format(obj.getCreateTime()));

            List<CA.Diagnosis> diagnosisList = new ArrayList<>();
            CA.Diagnosis diagnosis = new CA.Diagnosis();
            diagnosis.setDiagnosisCode(obj.getDisCode());
            diagnosis.setDiagnosisName(obj.getDialectical());
            diagnosisList.add(diagnosis);
            if (obj.getDType() == 1 || obj.getDType() == 3) {
                diagnosis = new CA.Diagnosis();
                diagnosis.setDiagnosisCode(obj.getZDisCode());
                diagnosis.setDiagnosisName(obj.getZDialectical());
                diagnosisList.add(diagnosis);
            }
            ca.setDiagnosisList(diagnosisList);

            List<CA.Drug> drugs = new ArrayList<>();
            List<RxDrugs> dlist = rxDrugsRepository.findAllByRxOrderNo(obj.getRxOrderNO());
            dlist.forEach(m -> {
                CA.Drug drug = new CA.Drug();
                drug.setHospitalDrugCode(m.getDrugId().toString());
                drug.setDrugCommonName(m.getDrugName());
                drug.setPrice(m.getPrice().toString());
                drug.setDeliverNumUnit(m.getNum().toString());
                drug.setMoney(m.getPrice().multiply(new BigDecimal(m.getNum())).toString());
                drugs.add(drug);
            });
            ca.setDrugList(drugs);

            obj.setTrialPharmSignatureXml(XmlUtils.convertToXml(ca));
        }
        boolean flag = false;
        try {
            rxMainRepository.save(obj);
            flag = true;
        } catch (Exception e) {
        }

        if (!flag) {
            CheckUtils.checkNull(null, new ApiException(10000, "处方审核失败"));
        } else {
            // 审核不通过 发送消息
            if(obj.getChkStatus() == 2)
                CompletableFuture.runAsync(() -> sendNotice(obj));
        }
        String wxaCode = "";
        if(re.getIsPc())
            wxaCode = createWxUnlimited(obj.getRxOrderNO(),objdoc);
        return wxaCode;
    }

    private void sendNotice(RxMain obj){
        MsgConfig msgConfig = msgConfigRepository.findById("Doctor_PrescriptionNoPass").orElse(null);
        if(msgConfig == null)
            return;        
        String token = wxSendMessage.getAccessToken(doctormappID, doctormappsecret);
        if(token == null)
            return;
        
        OrderMain order = orderMainRepository.findById(obj.getOrderNO()).orElse(null); 
        DoctorBaseInfo doctor = doctorBaseInfoRepository.findById(order.getDcId()).orElseThrow(() -> new ApiException(1, "未查询到数据"));
        
        WxSubScribeMessageVo stemp = new WxSubScribeMessageVo();
        stemp.setTouser(doctor.getOpenId());
        stemp.setTemplate_id(msgConfig.getTemplateId());
        stemp.setPage("pages/index/index");

        Map<String, WxSubScribeMessageVo.TemplateData> sdata = new HashMap<>();
        sdata.put("phrase1", new WxSubScribeMessageVo.TemplateData("不通过"));        
        SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdata.put("date3", new WxSubScribeMessageVo.TemplateData(sdf.format(obj.getChkTime())));
        sdata.put("thing4", new WxSubScribeMessageVo.TemplateData(obj.getFailureReason()));
        stemp.setData(sdata);
        wxSendMessage.sendSubscribeMessage(stemp, token);
    }

    @Value("${mappID}")
    private String mappID;

    @Value("${mappsecret}")
    private String mappsecret;

    private String createWxUnlimited(String rxOrderNo, Pharmacist objdoc) {
        String token = wxSendMessage.getAccessToken(mappID, mappsecret);
        Map<String, String> req = new HashMap<>();
        req.put("scene", rxOrderNo);  
        req.put("page", "pages/index/sign/handSign");
        return wxSendMessage.createWxaCode(token, req);
    }

    @Override
    public OrderPatients getOrderPatientsInfo(Long PID, String OrderNO) {
        OrderPatients obj = orderRxMainMapper.getOrderPatients(PID, OrderNO);
        switch (obj.getFirst()) {
            case 1:
                obj.setFirstName("本院本医生");
                break;
            case 2:
                obj.setFirstName("非本院复诊");
                break;
            case 3:
                obj.setFirstName("本院其他医生");
                break;

            default:
                break;
        }
        obj.setImg(imgRepository.findAllBypatientsID(obj.getID()));
        return obj;
    }

    @Override
    public HashMap<String, Object> getPrescription(int Page, int Limit, int ChkStatus, long DCID) {
        int CountYes = rxMainRepository.findCountByDcId(DCID, 1);
        int CountNo = rxMainRepository.findCountByDcId(DCID, 2);
        int CountRxMain = rxMainRepository.findAllCountByDcId(DCID);

        int Num = (Page - 1) * Limit;
        if (Num < 0) Num = 0;
        List<Prescription> obj = orderRxMainMapper.getPrescription(DCID, ChkStatus, Num, Limit);

        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("CountYes", CountYes);
        hashMap.put("CountNo", CountNo);
        hashMap.put("CountRxMain", CountRxMain);
        hashMap.put("RxMain", obj);
        return hashMap;
    }

    @Override
    public List<EnumConfig> getEnumConfig() {
        List<EnumConfig> list = enumConfigRepository.findAllByEtype();
        return list;
    }

    @Override
    public Map<String, Object> rxStatistics() {
        long dcId = userUtils.getUserID();

        Date now = new Date();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

        Date beg = null, end = null;
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 24);

            beg = df.parse(df.format(now));
            end = df.parse(df.format(calendar.getTime()));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int todayNo = pharmacistRepository.findCountTodayByDcId(dcId, 0, beg, end);
        int todayYes = pharmacistRepository.countTodayChecked(dcId, beg, end);
        int CountNo = rxMainRepository.findCountByDcId(dcId, 2);
        int CountRxMain = rxMainRepository.findAllCountByDcId(dcId);

        Map<String, Object> res = new HashMap<>();
        res.put("todayNo", todayNo);
        res.put("todayYes", todayYes);
        res.put("CountNo", CountNo);
        res.put("CountRx", CountRxMain);

        return res;
    }

    @Override
    public Map<String, Object> rxList(RxListReq req) {
        int skip = (req.getPageNum() - 1) * req.getPageSize();
        if (skip < 0) skip = 0;

        long dcid = userUtils.getUser().getDcId();
        if (req.getBeg() != null && req.getEnd() != null) {
            Calendar ca = Calendar.getInstance();
            ca.setTime(req.getEnd());
            ca.add(Calendar.DAY_OF_MONTH, 1);
            req.setEnd(ca.getTime());
        }
        List<Map<String, Object>> list = orderRxMainMapper.rxList(dcid, req.getBeg(), req.getEnd(), req.getDType(), req.getChkStatus(), req.getName(), skip, req.getPageSize());
        int count = orderRxMainMapper.rxCount(dcid, req.getBeg(), req.getEnd(), req.getDType(), req.getChkStatus(), req.getName());
        Map<String, Object> res = new HashMap<>();
        list.forEach(m -> {
            m.put("DTypeName", DType.valueToDesc(Integer.valueOf(m.get("DType").toString())));
            m.put("ChkStatus", ChkStatus.valueToDesc(Integer.valueOf(m.get("ChkStatus").toString())));
            m.put("ChkTime", m.get("ChkTime") == null ? "/" : m.get("ChkTime"));
        });
        res.put("list", list);
        res.put("cnt", count);
        return res;
    }

    /**
     * 返回用户信息
     *
     * @param phone 用户手机号
     * @return 返回用户激活信息
     */
    @Override
    public Map<String, String> getCaMessage(String phone) {
        Map<String, String> map = new HashMap<>(MapUtils.getMapInitSize(3));
        String msspId = pharmacistRepository.getCaMessage(phone);

        // 查询用户
        String caResult = caSendMessage.queryUserInfo(msspId);
        JSONObject jsonObject = JSONObject.parseObject(caResult);
        if (CaSendMessage.SUCCESS.equals(jsonObject.get(CaSendMessage.MESSAGE))) {

            String userStatus = JSONObject.parseObject(jsonObject.get("data").toString()).get("userStatus").toString();
            if (CaSendMessage.NOT_ACTIVE.equals(userStatus)) {
                String resultMap = redisUtils.get("ca" + phone).toString();
                String[] split = resultMap.split(":");
                map.put("msspId", split[0]);
                map.put("authCode", split[1]);
                // 用户未激活
                map.put("userStatus", CaSendMessage.NOT_ACTIVE);
                redisUtils.delete("ca" + phone);

            } else if (CaSendMessage.NOT_EXIST.equals(userStatus)) {
                // 用户不存在或者已经促销
                map.put("userStatus", CaSendMessage.NOT_EXIST);

            } else if (CaSendMessage.LOCKED.equals(userStatus)) {
                // 用户被冻结
                map.put("userStatus", CaSendMessage.LOCKED);

            } else if (CaSendMessage.ACTIVE.equals(userStatus)) {
                // 用户已激活
                map.put("msspId", msspId);
                map.put("userStatus", CaSendMessage.ACTIVE);
            }

        }
        return map;
    }

    /**
     * 添加签名任务
     *
     * @param orderId 订单id
     * @return 返回ca 签名任务
     */
    @Override
    public Map<String, String> addSignJob(String orderId, String msspId) {
        String xml = rxMainRepository.getXml(orderId);
        String time = String.valueOf(System.currentTimeMillis());
//        Map<String, String> map = new HashMap<>(MapUtils.getMapInitSize(1));

        //获得参数签名id
        CompletableFuture<String> exceptionally = CompletableFuture.supplyAsync(() -> {
            // 发送请求
            return caSendMessage.getSignJob(msspId, xml);
        }, threadPoolExecutor);


        // 发起时间戳签名
        CompletableFuture<String> caTime = CompletableFuture.supplyAsync(() -> {
            return caSendMessage.signtss(time);
        }, threadPoolExecutor);


        // 结果汇总
        CompletableFuture<Map<String, String>> mapCompletableFuture = exceptionally.thenCombineAsync(caTime, (result1, result2) -> {
            Map<String, String> map = new HashMap<>(MapUtils.getMapInitSize(2));
            // 获得签名数据
            JSONObject sigJob = JSONObject.parseObject(result1);
            if (CaSendMessage.SUCCESS.equals(sigJob.get(CaSendMessage.MESSAGE))) {
                JSONObject jsonData = JSONObject.parseObject(sigJob.get("data").toString());
                map.put("signJobId", jsonData.get("signJobId").toString());
            } else {
                throw new ApiException(500, JSONObject.parseObject(result1).get(CaSendMessage.MESSAGE).toString());
            }

            // 时间签名
            JSONObject jsonObject = JSONObject.parseObject(result2);
            if (CaSendMessage.SUCCESS.equals(sigJob.get(CaSendMessage.MESSAGE))) {
                JSONObject timeJson = JSONObject.parseObject(jsonObject.get("data").toString());
                redisUtils.set("catime" + orderId + "drug", time);
                map.put("timeSignature", timeJson.get("signature").toString());
            } else {
                throw new ApiException(500, JSONObject.parseObject(result2).get(CaSendMessage.MESSAGE).toString());
            }
            // 返回处理后的结果
            return map;
        });


        try {
            //获得结果
            return mapCompletableFuture.get();
        } catch (InterruptedException e) {
            throw new ApiException(400, e.getMessage());
        } catch (ExecutionException e) {

            String executionAdd = "com.example.common.support.ApiException: err";

            if (executionAdd.equals(e.getMessage())) {
                throw new ApiException(400, e.getMessage().split(":")[1]);
            } else {
                throw new ApiException(400, e.getMessage());
            }
        }

//        String signJob = caSendMessage.getSignJob(msspId, xml);
//        JSONObject jsonObject = JSONObject.parseObject(signJob);
//        if (CaSendMessage.SUCCESS.equals(jsonObject.get(CaSendMessage.MESSAGE))) {
//            JSONObject jsonData = JSONObject.parseObject(jsonObject.get("data").toString());
//            map.put("signJobId", jsonData.get("signJobId").toString());
//        } else {
//            throw new ApiException(500, JSONObject.parseObject(signJob).get(CaSendMessage.MESSAGE).toString());
//        }
//
//        return map;
    }

    /**
     * 获得签名任务结果
     *
     * @param signJobId 签名任务id
     * @param msspId    用户编号
     * @return 返回签名任务结果
     */
    @Override
    public Map<String, String> querySignJob(String signJobId, String msspId, String orderId) {
        String result = caSendMessage.querySignJob(signJobId);
        JSONObject jsonObject = JSONObject.parseObject(result);
        Map<String, String> map = new HashMap<>(MapUtils.getMapInitSize(5));

        if (CaSendMessage.SUCCESS.equals(jsonObject.get(CaSendMessage.MESSAGE))) {
            String dataStr = jsonObject.get("data").toString();
            // 转为map
            map.putAll(JSONObject.parseObject(dataStr, new TypeReference<Map<String, String>>() {
            }));
            int i = pharmacistRepository.updateSigJob(map.get("signCert"), map.get("signResult"), orderId);

            if (i < 0) {
                throw new ApiException(400, "证书保存失败");
            }

        } else {
            throw new ApiException(500, JSONObject.parseObject(result).get(CaSendMessage.MESSAGE).toString());
        }

        return map;
    }

    /**
     * 验证签名是否成功
     *
     * @param plain         原文
     * @param signResult    签名结果
     * @param cert          证书
     * @param orderId       订单id
     * @param timeSignature 时间戳签名值
     * @return 签名是否成功返回值
     */
    @Override
    public Map<String, String> verifySign(String plain, String signResult, String cert, String orderId, String timeSignature) {
        // redis中获得时间搓
        String timeStr = String.valueOf(redisUtils.get("catime" + orderId + "drug"));
        //发起参数验证请求
        CompletableFuture<String> verifyResult = CompletableFuture.supplyAsync(() -> {
            return caSendMessage.verifySign(plain, signResult, cert);
        }, threadPoolExecutor);

        // 发起时间戳校验请求
        CompletableFuture<String> timeResult = CompletableFuture.supplyAsync(() -> {
            return caSendMessage.verifytss(timeStr, signResult);
        }, threadPoolExecutor);

        // 任务进行聚合
        CompletableFuture<Map<String, String>> mapCompletableFuture = verifyResult.thenCombineAsync(timeResult, (result1, result2) -> {
            Map<String, String> map = new HashMap<>(MapUtils.getMapInitSize(1));
            if (!CaSendMessage.SUCCESS.equals(JSONObject.parseObject(result2).get(CaSendMessage.MESSAGE).toString())) {
                throw new ApiException(500, JSONObject.parseObject(result2).get(CaSendMessage.MESSAGE).toString());
            }

            if (CaSendMessage.SUCCESS.equals(JSONObject.parseObject(result1).get(CaSendMessage.MESSAGE).toString()) &&
                    CaSendMessage.SUCCESS.equals(JSONObject.parseObject(result2).get(CaSendMessage.MESSAGE).toString())) {

                int i = pharmacistRepository.updateVerify(orderId, timeSignature);

                if (i > 0) {
                    map.putAll(JSONObject.parseObject(result1, new TypeReference<Map<String, String>>() {
                    }));
                    redisUtils.delete("catime" + orderId + "drug");
                }
            } else {
                throw new ApiException(500, JSONObject.parseObject(result1).get(CaSendMessage.MESSAGE).toString());
            }
            return map;
        });

        try {
            return mapCompletableFuture.get();
        } catch (InterruptedException e) {
            throw new ApiException(400, e.getMessage());
        } catch (ExecutionException e) {
            String errorPath = "com.example.common.support.ApiException: err";

            if (errorPath.equals(e.getMessage())) {
                throw new ApiException(400, e.getMessage().split(":")[1]);
            } else {
                throw new ApiException(400, e.getMessage());
            }
        }
    }
    
    @Override
    public Boolean isCaSess(String rxOrderNo){
        RxMain rx = rxMainRepository.findById(rxOrderNo).orElseThrow(() -> new ApiException(10000, "订单不存在"));
        return rx.getIsTrialPharmCa();
    }
    
    @Override
    public Map<String,Object> getCaOrder(String rxorderno){
        RxMain rx = rxMainRepository.findById(rxorderno).orElseThrow(() -> new ApiException(10000, "订单不存在"));
        Pharmacist ph = pharmacistRepository.findById(rx.getChkDcId()).orElseThrow(() -> new ApiException(10000, "订单不存在"));
        Map<String, Object> res = new HashMap<>();
        res.put("RxOrderNO", rx.getRxOrderNO());
        res.put("OpenId", ph.getOpenId());
        res.put("Phone", ph.getPhone());

        return res;
    }
}
